<!-- AMapContainer.vue -->
<template>
  <div id="mapContainer" ref="mapContainer" style="width: 100%; height: 100vh;"></div>
  <MapControls :AMap="AMap" :map="map"></MapControls>
  <div id="panel"></div>
</template>

<script setup>
import { ref, shallowRef, onMounted, onUnmounted } from 'vue';
import { createApp } from 'vue'; // 引入 createApp
import AMapLoader from '@amap/amap-jsapi-loader';
import CustomInfoWindow from './CustomInfoWindow.vue';
import MapControls from "./MapControls.vue";
import axios from "axios"; // 引入你的自定义弹窗组件
const mapContainer = ref(null);
// 地图实例和信息窗体实例
const map = ref(null);
const local = ref(null);
const AMap = ref(null);
const infoWindow = shallowRef(null);

// 接收父组件传递的配置和标记点数据
const props = defineProps({
  mapKey: String,
  securityJsCode: String,
  center: {
    type: Array,
    default: () => [116.397428, 39.90923]
  },
  zoom: {
    type: Number,
    default: 11
  },
  markers: Array // 格式: { position: [lng, lat], title: '', content: '', ...自定义属性 }
});

// 初始化地图
onMounted(() => {
  initMap();
});

onUnmounted(() => {
  map.value?.destroy();
});

const initMap = async () => {
  window._AMapSecurityConfig = {
    securityJsCode: props.securityJsCode
  };

  try {
    AMap.value = await AMapLoader.load({
      key: props.mapKey,
      version: '2.0',
      plugins: ['AMap.InfoWindow', 'AMap.ControlBar','AMap.ToolBar','AMap.PolylineEditor','AMap.MoveAnimation'],
      //加载 AMapUI
      AMapUI: {
        version: "1.1", // AMapUI 版本
      },
      keyboardEnable: true, // 允许键盘操作
      Loca:{                // 是否加载 Loca， 缺省不加载
        version: '2.0.0'  // Loca 版本，缺省 1.3.2
      },
    });
    // map.value = new  AMap.value.Map('mapContainer', {
    //   // rotateEnable:true,
    //   // pitchEnable:true,
    //   zoom: 17,
    //   pitch: 50,
    //   rotation: -15,
    //   viewMode:'2D', //开启3D视图,默认为关闭
    //   zooms:[2,20],
    //   center:[116.333926,39.997245]
    // });

   map.value = new  AMap.value.Map('mapContainer', {
     viewMode: '3D',
     zoom: 11.8,
     center: [121.304018, 31.217688],
     mapStyle: 'amap://styles/grey',
     showBuildingBlock: false,
     showLabel: false,
    });

    // 关键：初始化Loca容器
    local.value = new Loca.Container({
      map: map.value,
    });

    // console.log(loca.value,'loca.value')

    const controlBar = new AMap.value.ControlBar({
      position:{
        right:'10px',
        top:'10px'
      }
    });
    controlBar.addTo(map.value);

    const toolBar = new AMap.value.ToolBar({
      position:{
        right:'40px',
        top:'110px'
      }
    });
    toolBar.addTo(map.value);

    // const overviewMap = new AMap.value.HawkEye({
    //   visible: true,
    // })

    // 初始化一个空的信息窗体实例，后续动态设置内容
    // infoWindow.value = new  AMap.value.InfoWindow({
    //   isCustom: true, // 必须设置为自定义窗体:cite[2]:cite[3]
    //   closeWhenClickMap: true // 点击地图关闭窗体
    // });

    // 添加标记点
    // addMarkers();
    // 添加多边形
    // addPolygon()
    // placeSearch();


    // addControl(new AMap.value.Scale());
    // addMarkAndCircle()
    // addOverlayGroup();
    // 添加图层
    // addLayers();
    // loadGeoJson();
    // addCustomMarks();
    // addMoremarks();
    // twoDotLine();
    // map.value.setMapStyle('amap://styles/darkblue')
    // editLine();
    // moveAnimation();
    // addDistrictMap();
    // 动画效果
    // setAnimate();
  } catch (error) {
    console.error('地图加载失败:', error);
  }
};

const setAnimate = ()=> {
  const loca = local.value;
  loca.ambLight = {
    intensity: 2.2,
    color: '#babedc',
  };
  loca.dirLight = {
    intensity: 0.46,
    color: '#d4d4d4',
    target: [0, 0, 0],
    position: [0, -1, 1],
  };
  loca.pointLight = {
    color: 'rgb(15,19,40)',
    position: [121.5043258, 31.2392241, 2600],
    intensity: 25,
    // 距离表示从光源到光照强度为 0 的位置，0 就是光不会消失。
    distance: 3900,
  };
  var geo = new Loca.GeoJSONSource({
    url: 'https://a.amap.com/Loca/static/loca-v2/demos/mock_data/sh_building_center.json',
  });

  var pl = window.pl = new Loca.PolygonLayer({
    zIndex: 120,
    shininess: 10,
    hasSide: true,
    cullface: 'back',
    depth: true,
  });

  pl.setSource(geo);
  pl.setStyle({
    topColor: '#111',
    height: function (index, feature) {
      return feature.properties.h;
    },
    textureSize: [1000, 820],
    texture: 'https://a.amap.com/Loca/static/loca-v2/demos/images/windows.jpg',
  });
  pl.setLoca(loca);

  var dat = new Loca.Dat();
  dat.addLight(loca.ambLight, loca, '环境光');
  dat.addLight(loca.dirLight, loca, '平行光');
  dat.addLight(loca.pointLight, loca, '点光');
  dat.addLayer(pl, '楼块');

  map.value.on('complete', function () {
    loca.animate.start();
    // document.querySelector('.start-btn').addEventListener('click', function () {
    setTimeout(animate, 2000);
  });

  function animate () {
    var speed = 1;
    // 镜头动画
    map.value.setZoom(11.8, true);
    map.value.setPitch(0, true);
    map.value.setCenter([121.304018, 31.217688], true);
    map.value.setRotation(1, true);
    pl.hide(1000);

    // 下钻
    loca.viewControl.addAnimates([{
      pitch: {
        value: 0,
        control: [[0, 20], [1, 0]],
        timing: [0, 0, 0.8, 1],
        duration: 3000 / speed,
      },
      zoom: {
        value: 15.9,
        control: [[0, 12.8], [1, 15.9]],
        timing: [0, 0, 0.8, 1],
        duration: 3000 / speed,
      },
      rotation: {
        value: -20,
        control: [[0, 20], [1, -20]],
        timing: [0, 0, 0.8, 1],
        duration: 2000 / speed,
      },
    }], function () {
      setTimeout(function () {
        pl.show(2000);
      }, 3000);

      loca.viewControl.addAnimates([
        // 寻迹
        {
          center: {
            value: [121.500419, 31.238089],
            control: [[121.424503326416,
              31.199146851153124], [121.46656036376952,
              31.245828642661486]],
            timing: [0.3, 0, 0.1, 1],
            duration: 8000 / speed,
          },
          zoom: {
            value: 17,
            control: [[0.3, 15], [1, 17]],
            timing: [0.3, 0, 0.7, 1],
            duration: 4000 / speed,
          },
          pitch: {
            value: 50,
            control: [[0.3, 0], [1, 50]],
            timing: [0.3, 0, 1, 1],
            duration: 3000 / speed,
          },
          rotation: {
            value: -80,
            control: [[0, -20], [1, -80]],
            timing: [0, 0, 1, 1],
            duration: 1000 / speed,
          },
        }, {
          // 环绕
          pitch: {
            value: 50,
            control: [[0, 40], [1, 50]],
            timing: [0.3, 0, 1, 1],
            duration: 7000 / speed,
          },
          rotation: {
            value: 260,
            control: [[0, -80], [1, 260]],
            timing: [0, 0, 0.7, 1],
            duration: 7000 / speed,
          },
          zoom: {
            value: 17,
            control: [[0.3, 16], [1, 17]],
            timing: [0.3, 0, 0.9, 1],
            duration: 5000 / speed,
          },
        }, {
          // 拉起
          center: {
            value: [121.500419, 31.238089],
            control: [[121.49986267089844,
              31.227628422210365], [121.49969100952148,
              31.24025152837923]],
            timing: [0.3, 0, 0.7, 1],
            duration: 2000 / speed,
          },
          pitch: {
            value: 0,
            control: [[0, 0], [1, 100]],
            timing: [0.1, 0, 0.7, 1],
            duration: 2000 / speed,
          },
          rotation: {
            value: 361,
            control: [[0, 260], [1, 361]],
            timing: [0.3, 0, 0.7, 1],
            duration: 2000 / speed,
          },
          zoom: {
            value: 13.8,
            control: [[0, 17.5], [1, 13.8]],
            timing: [0.3, 0, 0.7, 1],
            duration: 2500 / speed,
          },
        }], function () {
        pl.hide(1000);
        setTimeout(animate, 2000);
        console.log('结束');
      });
    });
  }
}

const addDistrictMap = ()=>{
  //2、创建世界简易行政区图层
  const distCountry = new AMap.value.DistrictLayer.Country({
    zIndex: 10, //设置图层层级
    zooms: [2, 15], //设置图层显示范围
    SOC: "CHN", //设置显示国家
    depth: 2, //设置数据显示层级，0：显示国家面，1：显示省级，当国家为中国时设置depth为2的可以显示市一级
  });

//3、设置行政区图层样式
  distCountry.setStyles({
    "stroke-width": 2, //描边线宽
    fill: function (data) {
      //设置区域填充颜色，可根据回调信息返回区域信息设置不同填充色
      //回调返回区域信息数据，字段包括 SOC(国家代码)、NAME_ENG(英文名称)、NAME_CHN(中文名称)等
      //国家代码名称说明参考 https://a.amap.com/jsapi_demos/static/demo-center/js/soc-list.json
      return "#ffffffe7";
    },
  });

  map.value.add(distCountry); //添加到地图实例中
}

const moveAnimation = ()=> {
  AMap.value.plugin(['AMap.MoveAnimation'], () => {
    let lineArr = [[116.478935, 39.997761], [116.478939, 39.997825], [116.478912, 39.998549], [116.478912, 39.998549], [116.478998, 39.998555], [116.478998, 39.998555], [116.479282, 39.99856], [116.479658, 39.998528], [116.480151, 39.998453], [116.480784, 39.998302], [116.480784, 39.998302], [116.481149, 39.998184], [116.481573, 39.997997], [116.481863, 39.997846], [116.482072, 39.997718], [116.482362, 39.997718], [116.483633, 39.998935], [116.48367, 39.998968], [116.484648, 39.999861]];
    const lineArr1 = lineArr.map((item) => {
      return new AMap.value.LngLat(item[0], item[1]);
    });

    console.log(lineArr1,'lineArr1')
    const marker = new AMap.value.Marker({
      map: map.value,
      // [116.478935, 39.997761]
      position: [116.483633,39.998935],
      icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
      offset: new AMap.value.Pixel(-13, -26),
    });
    console.log(lineArr, marker)

    const polyline = new AMap.value.Polyline({
      map: map.value,
      path: lineArr1,
      showDir: true,
      strokeColor: "#28F",  //线颜色
      // strokeOpacity: 1,     //线透明度
      strokeWeight: 6,      //线宽
      // strokeStyle: "solid"  //线样式: lineArr,
    })

    const passedPolyline = new AMap.value.Polyline({
      map: map.value,
      strokeColor: "#AF5",  //线颜色
      strokeWeight: 6,      //线宽
    })

    marker.on('moving', function (e) {
      passedPolyline.setPath(e.passedPath);
      map.value.setCenter(e.target.getPosition(), true)
    });
    // 自动调整范围让其完整展示
    map.value.setFitView();

    setTimeout(() => {
      marker.moveAlong(lineArr1, {
        duration: 1000,
        autoRotation: true,
        aniInterval: 0,
        circlable: true,
      })
      console.log('开始动画')
    }, 1000)
  })

}


const editLine = ()=>{
  const path = [
    new AMap.value.LngLat(116.368904, 39.913423),
    new AMap.value.LngLat(116.382122, 39.901176),
    new AMap.value.LngLat(116.387271, 39.912501),
    new AMap.value.LngLat(116.398258, 39.9046),
  ];
  const polyline = new AMap.value.Polyline({
    path: path,
    borderWeight: 2, //线条宽度，默认为1
    strokeColor: "red", //线条颜色
    lineJoin: "round", //折线拐点连接处样式
  });
  map.value.add(polyline);

  const editor = new AMap.value.PolylineEditor(map.value,polyline);
  editor.open();
}

const twoDotLine = () => {
  const mark1 = new AMap.value.Marker({
    map: map.value,
    draggable: true,
    position: new AMap.value.LngLat(116.368904, 39.923423)
  })

  const mark2 = new AMap.value.Marker({
    map: map.value,
    draggable: true,
    position: new AMap.value.LngLat(116.387271, 39.922501)
  })

  const line = new AMap.value.Polyline({
    strokeColor:'#80d8ff',
    isOutline:true,
    outlineColor:'white',
  })
  line.setMap(map.value)
  const text = new AMap.value.Text({
    text:'',
    style:{'background-color':'#29b6f6',
      'border-color':'#e1f5fe',
      'font-size':'12px'},
  })

  text.setMap(map.value)

  function computeDis(){
   const p1 = mark1.getPosition();
   const p2 = mark2.getPosition();
    const textPos = p1.divideBy(2).add(p2.divideBy(2));
    const distance = Math.round(p1.distance(p2));
    const path = [p1,p2];
    line.setPath(path);
    text.setText('两点相距'+distance+'米')
    text.setPosition(textPos)
  }
  computeDis();
  mark1.on('dragend', computeDis);
  mark2.on('dragend', computeDis);
  // 地图设置区域
  map.value.setFitView();
}

// 海量Mark数据加载
const addMoremarks = () => {
  const labelsLayer = new AMap.value.LabelsLayer({
    zooms: [10, 20],
    zIndex: 1000,
    collision: true, //该层内标注是否避让
    allowCollision: true, //不同标注层之间是否避让
  });
  //设置一个图标对象
  const icon = {
    type: "image", //图标类型，现阶段只支持 image 类型
    image: "https://a.amap.com/jsapi_demos/static/demo-center/marker/express2.png", //可访问的图片 URL
    size: [64, 30], //图片尺寸
    anchor: "center", //图片相对 position 的锚点，默认为 bottom-center
  };
  //设置文字对象
  const text = {
    content: "中邮速递易", //要展示的文字内容
    direction: "right", //文字方向，有 icon 时为围绕文字的方向，没有 icon 时，则为相对 position 的位置
    offset: [-20, -5], //在 direction 基础上的偏移量
    //文字样式
    style: {
      fontSize: 12, //字体大小
      fillColor: "#22886f", //字体颜色
      strokeColor: "#fff", //描边颜色
      strokeWidth: 2, //描边宽度
    },
  };

  //创建 LabelMarker
  const labelMarker = new AMap.value.LabelMarker({
    name: "标注", //此属性非绘制文字内容，仅为标识使用
    position: [116.466994, 39.984904],
    zIndex: 16,
    rank: 1, //避让优先级
    icon: icon, //标注图标，将 icon 对象传给 icon 属性
    text: text, //标注文本，将 text 对象传给 text 属性
  });

  const labelMarker1 = new AMap.value.LabelMarker({
    name: "标注", //此属性非绘制文字内容，仅为标识使用
    position: [116.666994, 39.994904],
    zIndex: 16,
    rank: 1, //避让优先级
    icon: icon, //标注图标，将 icon 对象传给 icon 属性
    text: text, //标注文本，将 text 对象传给 text 属性
  });
  labelMarker.on('click', function(e){
    console.log('点击了')
    labelMarker.setOpacity(0.5);
  });
  labelsLayer.add([labelMarker, labelMarker1]);


  map.value.add(labelsLayer);


}


const addCustomMarks = ()=>{
  // 以 icon URL 的形式创建一个途经点
  const viaMarker = new AMap.value.Marker({
    position: new AMap.value.LngLat(116.38,39.92),
    // 将一张图片的地址设置为 icon
    icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png',
    // 设置了 icon 以后，设置 icon 的偏移量，以 icon 的 [center bottom] 为原点
    offset: new AMap.value.Pixel(-13, -30)
  });

  // 创建一个 Icon
  const startIcon = new AMap.value.Icon({
    // 图标尺寸
    size: new AMap.value.Size(25, 34),
    // 图标的取图地址
    image: '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png',
    // 图标所用图片大小
    imageSize: new AMap.value.Size(135, 40),
    // 图标取图偏移量
    imageOffset: new AMap.value.Pixel(-9, -3)
  });

  // 将 icon 传入 marker
  const startMarker = new AMap.value.Marker({
    // 位置经纬度
    position: new AMap.value.LngLat(116.35,39.89),
    icon: startIcon,
    // 偏移量
    offset: new AMap.value.Pixel(-13, -30)
  });

  // 创建一个 icon
  const endIcon = new AMap.value.Icon({
    size: new AMap.value.Size(25, 34),
    image: '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png',
    imageSize: new AMap.value.Size(135, 40),
    imageOffset: new AMap.value.Pixel(-95, -3)
  });

  // 将 icon 传入 marker
  const endMarker = new AMap.value.Marker({
    position: new AMap.value.LngLat(116.45,39.93),
    icon: endIcon,
    offset: new AMap.value.Pixel(-13, -30)
  });

  map.value.add([viaMarker, startMarker, endMarker]);
}

// 添加标记点并绑定点击事件
const addMarkers = () => {
  props.markers.forEach(markerData => {
    const marker = new  AMap.value.Marker({
      position: markerData.position,
      map: map.value,
      title: markerData.title
    });

    // 绑定标记点点击事件
    marker.on('click', () => {
      openInfoWindowWithVueComponent(markerData, marker.getPosition());
    });
  });
};

// 添加多边形
const addPolygon = ()=>{
  const pathArr = [
    [
      [
        [121.7789, 31.3102],
        [121.7279, 31.3548],
        [121.5723, 31.4361],
        [121.5093, 31.4898],
        [121.5624, 31.4864],
        [121.5856, 31.4547],
        [121.7694, 31.3907],
        [121.796, 31.3456],
        [121.7789, 31.3102],
      ],
    ],
  ];
  const polygon = new AMap.value.Polygon({
    path: pathArr, //多边形路径
    fillColor: "#ccebc5", //多边形填充颜色
    strokeOpacity: 1, //线条透明度
    fillOpacity: 0.5, //填充透明度
    strokeColor: "#2b8cbe", //线条颜色
    strokeWeight: 1, //线条宽度
    strokeStyle: "dashed", //线样式
    strokeDasharray: [5, 5], //轮廓的虚线和间隙的样式
  });

  polygon.on('mouseover',()=>{
    polygon.setOptions({
      fillOpacity: 0.7, //多边形填充透明度
      fillColor: "#7bccc4",
    });
  })

  //鼠标移出恢复样式
  polygon.on("mouseout", () => {
    polygon.setOptions({
      fillOpacity: 0.5,
      fillColor: "#ccebc5",
    });
  });

  map.value.add(polygon);
}

// 添加Mark和Circle
const addMarkAndCircle = () => {
  const marker = new  AMap.value.Marker({
    icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
    position: [116.405467, 39.907761],
  })

  const circle = new AMap.value.Circle({
    center: new AMap.value.LngLat("116.403322", "39.920255"), //圆心位置
    radius: 1000, //半径
    strokeColor: "#FF33FF", //线颜色
    strokeOpacity: 1, //线透明度
    strokeWeight: 3, //线宽
    fillColor: "#00BFFF", //填充颜色
    fillOpacity: 0.3, //填充透明度
  });

  map.value.add(marker);
  map.value.add(circle);

  console.log(map.value.getAllOverlays(), map.value.getAllOverlays('marker'))
}

// geojson 加载
const loadGeoJson = () => {
  AMap.value.plugin(["AMap.GeoJSON"], async function () {
    const response = await axios.get('https://a.amap.com/jsapi_demos/static/geojson/chongqing.json');
    const geoJSON = new AMap.value.GeoJSON({
      geoJSON: response.data,
      // 第一个是geojson数据，第二个是每个点的坐标
      getPolygon (geoJson, lngLats) {
        const area  = AMap.value.GeometryUtil.ringArea(lngLats[0])
        console.log(geoJson, lngLats)
        return new AMap.value.Polygon({
          path: lngLats,
          fillOpacity: 1 - Math.sqrt(area / 8000000000),// 面积越大透明度越高
          strokeColor: 'white',
          fillColor: 'red'
        });
      }
    })

      map.value.add(geoJSON);

    console.log(response.data,'response')
  })
}

const addLayers = ()=>{
  console.log('addLayers')
  //卫星图层
  const layer1 = new AMap.value.TileLayer.Satellite({
    visible: false, //是否显示图层
  });
  // 路网图层
  const layer2 = new AMap.value.TileLayer.RoadNet();
  map.value.add([layer1, layer2]);
}

const addOverlayGroup = ()=>{
  const polyline = new AMap.value.Polyline({
    path: [
      new AMap.value.LngLat("116.368904", "39.913423"),
      new AMap.value.LngLat("116.382122", "39.901176"),
    ],
  });

  const circle = new AMap.value.Circle({
    center: new AMap.value.LngLat("116.407745", "39.917578"), //圆心
    radius: 50, //半径 单位：米
  });

  const overlayGroup = new AMap.value.OverlayGroup([polyline, circle]);

  //对此覆盖物群组设置同一属性
  overlayGroup.setOptions({
    strokeColor: "red",
    strokeWeight: 5,
  });

  map.value.add(overlayGroup);

}

const placeSearch = ()=> {
  AMap.value.plugin(["AMap.PlaceSearch"], function () {
    const placeSearch = new AMap.value.PlaceSearch({
      pageSize: 5, // 单页显示结果条数
      pageIndex: 1, // 页码
      city: "010", // 兴趣点城市
      // citylimit: true,  //是否强制限制在设置的城市内搜索
      // map: map.value, // 展现结果的地图实例
      // panel: "panel", // 结果列表将在此容器中进行展示。
      autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
    });
    //在回调函数中使用插件功能
    placeSearch.search("北京", function (status, result) {
     setTimeout(()=>{
       const pois = result.poiList.pois;
       const point = pois[0].location;
       map.value.setCenter([point.lng, point.lat]);
       //查询成功时，result 即对应匹配的 POI 信息
       console.log(status, result)
     },3000)
    });
  })
}

// 核心方法：打开信息窗体，并将Vue组件作为内容
const openInfoWindowWithVueComponent = (markerData, position) => {
  if (!map.value || !infoWindow.value) return;

  // 1. 创建一个容器元素
  const contentEl = document.createElement('div');

  // 2. 使用 createApp 创建并挂载一个 Vue 应用实例
  const app = createApp(CustomInfoWindow, {
    // 传递 props 给弹窗组件
    title: markerData.title,
    content: markerData.content,
    markerData: markerData, // 传递整个数据对象
    // 监听子组件发出的事件
    onClose: () => {
      // 关闭信息窗体
      infoWindow.value.close();
      // 卸载 Vue 应用实例，释放内存
      app.unmount();
    },
    onActionClick: (data) => {
      console.log('触发了详情操作:', data);
      // 这里可以处理业务逻辑，也可以向上层组件发射事件
    }
  });

  // 3. 将应用挂载到创建的DOM元素上
  app.mount(contentEl);

  // 4. 将挂载后的DOM元素设置为信息窗体的内容
  infoWindow.value.setContent(contentEl);

  // 5. 在地图上指定位置打开信息窗体:cite[2]:cite[3]
  infoWindow.value.open(map.value, position);
};

// 暴露方法给父组件，例如允许父组件主动关闭弹窗
defineExpose({
  closeWindow: () => infoWindow.value?.close()
});
</script>

<style scoped>
#mapContainer {
  width: 100vw;
  height: 100vh;
}

#panel {
  position: absolute;
  background-color: white;
  max-height: 90%;
  overflow-y: auto;
  top: 10px;
  right: 10px;
  width: 280px;
}
</style>